Make dom0_vcpus_pin a platform independant option.
authorEmmanuel Ackaouy <ack@xensource.com>
Mon, 25 Sep 2006 15:31:02 +0000 (16:31 +0100)
committerEmmanuel Ackaouy <ack@xensource.com>
Mon, 25 Sep 2006 15:31:02 +0000 (16:31 +0100)
By default, it's off. When enabled on the command line, it
causes dom0's VCPUs to be pinned to their respective physical
CPUs at creation time. Once pinned, they can never be moved.
ALso cleanup VCPU initialization of scheduler parameters.
Signed-off-by: Emmanuel Ackaouy <ack@xensource.com>
docs/src/user.tex
xen/arch/ia64/xen/domain.c
xen/arch/ia64/xen/xensetup.c
xen/common/domain.c
xen/common/schedule.c
xen/include/xen/sched.h

index 52c2d746b215237bc211c6595b8c119f522a5002..6b4e5cfa728035a3a0285a7467db9e7940d5ba33 100644 (file)
@@ -3208,6 +3208,8 @@ editing \path{grub.conf}.
   respectively; if no suffix is specified, the parameter defaults to
   kilobytes. In previous versions of Xen, suffixes were not supported
   and the value is always interpreted as kilobytes.
+\item [ dom0\_vcpus\_pin ] Pins domain 0 VCPUs on their respective
+  physical CPUS (default=false).
 \item [ tbuf\_size=xxx ] Set the size of the per-cpu trace buffers, in
   pages (default 0).  
 \item [ sched=xxx ] Select the CPU scheduler Xen should use.  The
index 17ca6ff40e4c8ca3c5a43e02b996b2e728925b0e..2073fd52c79bdae7e342127e2221ccbddd0c84de 100644 (file)
@@ -54,7 +54,6 @@ unsigned long dom0_align = 64*1024*1024;
 static unsigned int dom0_max_vcpus = 1;
 integer_param("dom0_max_vcpus", dom0_max_vcpus); 
 
-extern int opt_dom0_vcpus_pin;
 extern unsigned long running_on_sim;
 
 extern char dom0_command_line[];
@@ -1021,12 +1020,9 @@ int construct_dom0(struct domain *d,
            dom0_max_vcpus = MAX_VIRT_CPUS;
        
        printf ("Dom0 max_vcpus=%d\n", dom0_max_vcpus);
-       for ( i = 1; i < dom0_max_vcpus; i++ ) {
+       for ( i = 1; i < dom0_max_vcpus; i++ )
            if (alloc_vcpu(d, i, i) == NULL)
                printf ("Cannot allocate dom0 vcpu %d\n", i);
-           else if (opt_dom0_vcpus_pin)
-               d->vcpu[i]->cpu_affinity = cpumask_of_cpu(i);
-       }
 
        /* Copy the OS image. */
        loaddomainelfimage(d,image_start);
index 4b9095c38d1e4827e240c8b03230ff4f23a07564..44a4c5108584b7c703b5c3364943a78f389fc6ea 100644 (file)
@@ -48,10 +48,6 @@ extern void mem_init(void);
 extern void init_IRQ(void);
 extern void trap_init(void);
 
-/* opt_dom0_vcpus_pin: If true, dom0 VCPUs are pinned. */
-unsigned int opt_dom0_vcpus_pin = 0;
-boolean_param("dom0_vcpus_pin", opt_dom0_vcpus_pin);
-
 /* opt_nosmp: If true, secondary processors are ignored. */
 static int opt_nosmp = 0;
 boolean_param("nosmp", opt_nosmp);
@@ -520,10 +516,6 @@ printk("num_online_cpus=%d, max_cpus=%d\n",num_online_cpus(),max_cpus);
                        0) != 0)
         panic("Could not set up DOM0 guest OS\n");
 
-    /* PIN domain0 VCPU 0 on CPU 0. */
-    if (opt_dom0_vcpus_pin)
-        dom0->vcpu[0]->cpu_affinity = cpumask_of_cpu(0);
-
     if (!running_on_sim)  // slow on ski and pages are pre-initialized to zero
        scrub_heap_pages();
 
index 1138a9aa5eb1892a158fea779f780a47dde9f2ea..2dde26eb755db85ee032735d7c6aa1197c5dece6 100644 (file)
@@ -82,20 +82,16 @@ struct vcpu *alloc_vcpu(
 
     v->domain = d;
     v->vcpu_id = vcpu_id;
-    v->processor = cpu_id;
     v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id];
     spin_lock_init(&v->pause_lock);
 
-    v->cpu_affinity = is_idle_domain(d) ?
-        cpumask_of_cpu(cpu_id) : CPU_MASK_ALL;
-
     v->runstate.state = is_idle_vcpu(v) ? RUNSTATE_running : RUNSTATE_offline;
     v->runstate.state_entry_time = NOW();
 
     if ( (vcpu_id != 0) && !is_idle_domain(d) )
         set_bit(_VCPUF_down, &v->vcpu_flags);
 
-    if ( sched_init_vcpu(v) < 0 )
+    if ( sched_init_vcpu(v, cpu_id) < 0 )
     {
         free_vcpu_struct(v);
         return NULL;
index 61f8f4c3debf3bb16695bf4f5e9118f7dd63686c..0b5ab9501ca8a5d0ab909af2a9f8d3cb26c3e03c 100644 (file)
@@ -37,6 +37,11 @@ extern void arch_getdomaininfo_ctxt(struct vcpu *,
 static char opt_sched[10] = "credit";
 string_param("sched", opt_sched);
 
+/* opt_dom0_vcpus_pin: If true, dom0 VCPUs are pinned. */
+static unsigned int opt_dom0_vcpus_pin;
+boolean_param("dom0_vcpus_pin", opt_dom0_vcpus_pin);
+
+
 #define TIME_SLOP      (s32)MICROSECS(50)     /* allow time to slip a bit */
 
 /* Various timer handlers. */
@@ -97,19 +102,38 @@ void vcpu_runstate_get(struct vcpu *v, struct vcpu_runstate_info *runstate)
     }
 }
 
-int sched_init_vcpu(struct vcpu *v) 
+int sched_init_vcpu(struct vcpu *v, unsigned int processor
 {
-    /* Initialise the per-domain timers. */
-    init_timer(&v->timer, vcpu_timer_fn, v, v->processor);
-    init_timer(&v->poll_timer, poll_timer_fn, v, v->processor);
+    const struct domain * const d = v->domain;
+
+    /* Initialize processor and affinity settings. */
+    v->processor = processor;
+
+    if ( is_idle_domain(d) || (d->domain_id == 0 && opt_dom0_vcpus_pin) )
+    {
+        /*
+         * The idler and potentially dom0 VCPUs are pinned onto their
+         * respective physical CPUs.
+         */
+        v->cpu_affinity = cpumask_of_cpu(processor);
 
-    if ( is_idle_vcpu(v) )
+        /* The idle VCPUs takes over their CPUs on creation... */
+        if ( is_idle_domain(d) )
+        {
+            per_cpu(schedule_data, v->processor).curr = v;
+            per_cpu(schedule_data, v->processor).idle = v;
+            set_bit(_VCPUF_running, &v->vcpu_flags);
+        }
+    }
+    else
     {
-        per_cpu(schedule_data, v->processor).curr = v;
-        per_cpu(schedule_data, v->processor).idle = v;
-        set_bit(_VCPUF_running, &v->vcpu_flags);
+        v->cpu_affinity = CPU_MASK_ALL;
     }
 
+    /* Initialise the per-domain timers. */
+    init_timer(&v->timer, vcpu_timer_fn, v, v->processor);
+    init_timer(&v->poll_timer, poll_timer_fn, v, v->processor);
+
     TRACE_2D(TRC_SCHED_DOM_ADD, v->domain->domain_id, v->vcpu_id);
 
     return SCHED_OP(init_vcpu, v);
@@ -212,6 +236,9 @@ int vcpu_set_affinity(struct vcpu *v, cpumask_t *affinity)
     cpumask_t online_affinity;
     unsigned long flags;
 
+    if ( v->domain->domain_id == 0 && opt_dom0_vcpus_pin )
+        return -EINVAL;
+
     cpus_and(online_affinity, *affinity, cpu_online_map);
     if ( cpus_empty(online_affinity) )
         return -EINVAL;
index 7e435bf2cfc37b3a10c80bcfa5af0e0c63b35010..93abe4e17f3abdb32e9a6c05349e9dad5fa37eba 100644 (file)
@@ -280,7 +280,7 @@ void new_thread(struct vcpu *d,
 #define set_current_state(_s) do { current->state = (_s); } while (0)
 void scheduler_init(void);
 void schedulers_start(void);
-int  sched_init_vcpu(struct vcpu *);
+int  sched_init_vcpu(struct vcpu *v, unsigned int processor);
 void sched_destroy_domain(struct domain *);
 long sched_adjust(struct domain *, struct xen_domctl_scheduler_op *);
 int  sched_id(void);